#!/usr/bin/python
import os
from StringIO import StringIO
from twisted.internet import reactor
from twisted.web import server, resource

from mediadart.config import Configurator
from mediadart.utils import normpath, get_mq_params
from mediadart import log

class LaunchError(Exception): pass

def check_dirs(conf):
    paths = [
             conf.get('LOG', 'logdir'),
             conf.get('STORAGE', 'temp_dir'),
             conf.get('STORAGE', 'cache_dir'),
            ]
    for path in paths:
        p = normpath(os.path.abspath(path))
        try:
            os.makedirs(p)
            log.info('Creating directory %s' % p)
        except OSError, e:
            if e.errno == 17:  # file exists
                pass
            else:
                raise


def get_servers(conf, section):
    server_names = [x for x in conf.options(section) if x.startswith('server_')]
    server_names.sort()
    server_list = [conf.get(section, x) for x in server_names]
    return server_list

def start_www(conf):
    try:
        interface = conf.get('WWW', 'host')
    except Exception, e:
        interface = ''
    port = conf.get('WWW', 'port')
    log.info('Starting WWW server on port %s:%s' % (interface, port))
    r = resource.Resource()
    reactor.listenTCP(int(port), server.Site(r), interface=interface)
    return r

def start_servers(server_list, *args, **kwargs):
    for server in server_list:
        try:
            p = server.split('.')
            #log.info('%s\n%s* Starting server: %s\n%s%s' % ('*'*60, ' '*18, '.'.join(p[:-1]), ' '*18, '*'*60))
            log.info('<$> launching server: %s' % '.'.join(p))
            m = __import__('.'.join(p[:-1]), fromlist = p[:-1])
            f = getattr(m, p[-1], None)
            if not f or not callable(f):
                raise Exception('%s is not callable' % f)
        except Exception, e:
            log.error('\n\n     *** IMPORT FAILURE for %s: %s\n' % (server, str(e)))
            continue

        try:
            f(*args, **kwargs)
        except Exception, e:
            log.error('\n\n     *** LAUNCH FAILURE for %s: %s\n' % (server, str(e)))

def format_configuration(s):
    "format configuration for printing"
    i = s.find('password = ')
    if i >= 0:
        j = s.find('\n', i)
        if j > i:
            t = s[i:j]
            s = s.replace(t, 'password = ******')
    return s

        

    

def start_all(msg):
    c = Configurator()
    check_dirs(c)
    s = StringIO()
    c.write(s)
    s.seek(0)
    s = format_configuration(s.read())
    log.debug('Active configuration\n| %s' % s.replace('\n', '\n| ') )
    log.info(msg)
    log.info('Configuration read from:\n * %s' % '\n * '.join(c.get_files()))
    try:
        servers = get_servers(c, 'WWW')
        if servers:
            log.info('******************** Starting WWW servers')
            root = start_www(c)
            start_servers(servers, root)
    except Exception, e:
        log.info(' * Error launching the www servers: %s' % str(e))
        return
    log.info('******************* End of WWW Servers Startup')
    try:
        servers = get_servers(c, 'MQUEUE')
        if servers:
            log.info('******************* Starting MQUEUE servers')
            conn_data = get_mq_params()
            log.info('Connecting to broker %s:%s, user=%s, vhost=%s' % (
                     conn_data['broker_ip'], conn_data['broker_port'], 
                     conn_data['username'], conn_data['vhost']))
            #log.info('Connecting to %s' % ', '.join(['%s:%s'%(x[0], v[0]) for x in get_mq_params()]))
            start_servers(servers)
    except Exception, e:
        log.info(' * Error launching the mqueue servers: %s' % str(e))
        return
    log.info('********************  End of MQUEUE Servers Startup')


def main(msg=''):
    reactor.callWhenRunning(start_all, msg)
    reactor.run()

if __name__=='__main__':
    main()
